package com.cc.security.config;

import com.cc.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

import javax.annotation.Resource;

//@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private UserService userService;
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();//加密算法
        //return NoOpPasswordEncoder.getInstance();//不适用加密
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /////////////////////////////基于内存/////////////////////////////
//        auth.inMemoryAuthentication()
//                .withUser("admin").password("123").roles("ADMIN", "USER")
//                .and()
//                .withUser("sang").password("123").roles("USER");
        /////////////////////////////基于数据库/////////////////////////////
        auth.userDetailsService(userService);
    }

    //    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests()
//                .antMatchers("/admin/**")
//                .hasRole("ADMIN")
//                .antMatchers("/user/**")
//                .access("hasAnyRole('ADMIN','USER')")
//                .antMatchers("/db/**")
//                .access("hasRole('ADMIN') and hasRole('DBA')")
//                .anyRequest()
//                .authenticated()
//                .and()
//                .formLogin()
//                .loginPage("/login_page")
//                .loginProcessingUrl("/login")
//                .usernameParameter("name")
//                .passwordParameter("passwd")
//                .successHandler(new AuthenticationSuccessHandler() {
//                    @Override
//                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
//                                                        Authentication auth) throws IOException, ServletException {
//                        Object principal = auth.getPrincipal();
//                        response.setContentType("application/json;charset=utf-8");
//                        PrintWriter out = response.getWriter();
//                        response.setStatus(200);
//                        Map<String, Object> map = new HashMap<>();
//                        map.put ("status",200);
//                        map.put("msg",principal);
//
//                        ObjectMapper om = new ObjectMapper();
//                        out.write(om.writeValueAsString(map));
//                        out.flush();
//                        out.close();
//
//                    }
//                })
//                .failureHandler(new AuthenticationFailureHandler() {
//                    @Override
//                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
//                                                        AuthenticationException exception) throws IOException, ServletException {
//
//                        response.setContentType("application/json;charset=utf-8");
//                        PrintWriter out = response.getWriter();
//                        response.setStatus(401);
//                        Map<String, Object> map = new HashMap<>();
//                        map.put ("status",401);
//                        if (exception instanceof LockedException) {
//                            map.put("msg","账户被锁定，请联系管理员!");
//                        } else if (exception instanceof CredentialsExpiredException) {
//                            map.put("msg","密码过期，请联系管理员!");
//                        } else if (exception instanceof AccountExpiredException) {
//                            map.put("msg","账户过期，请联系管理员!");
//                        } else if (exception instanceof DisabledException) {
//                            map.put("msg","账户被禁用，请联系管理员!");
//                        } else if (exception instanceof BadCredentialsException) {
//                            map.put("msg","用户名或者密码输入错误，请重新输入!");
//                        }else{
//                            map.put("msg","登录失败");
//                        }
//                        ObjectMapper om = new ObjectMapper();
//                        out.write(om.writeValueAsString(map));
//                        out.flush();
//                        out.close();
//                    }
//                })
//                .and()
//                .logout()
//                .logoutUrl ("/logout")
//                .clearAuthentication(true)
//                .invalidateHttpSession(true)
//                .addLogoutHandler(new LogoutHandler() {
//                            @Override
//                            public void logout(HttpServletRequest req, HttpServletResponse resp, Authentication auth) {
//
//                            }
//                })
//                .logoutSuccessHandler(new LogoutSuccessHandler() {
//                                @Override
//                                public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth)
//                                throws IOException {
//                                    resp.sendRedirect("/login_page");
//                                }
//
//                })
//                .permitAll()
//                .and()
//                .csrf()
//                .disable();
//    }
    //*****************************基于数据库认证*****************************
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests()
//                .antMatchers("/admin/**").hasRole("admin")
//                .antMatchers("/db/**").hasRole("dba")
//                .antMatchers("/user/**").hasRole("user")
//                .anyRequest().authenticated()
//                .and()
//                .formLogin()
//                .loginProcessingUrl("/login").permitAll()
//                .and()
//                .csrf().disable ();
//    }
//*****************************基于数据库认证动态权限*****************************
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()

                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>
                        () {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {
                        object.setSecurityMetadataSource(cfisms());
                        object.setAccessDecisionManager(cadm());
                        return object;
                    }
                })
                .and()
                .formLogin()
                .loginProcessingUrl("/login").permitAll()
                .and()
                .csrf()
                .disable();
    }

    @Bean
    CustomFilterInvocationSecurityMetadataSource cfisms() {
        return new CustomFilterInvocationSecurityMetadataSource();
    }

    @Bean
    CustomAccessDecisionManager cadm() {
        return new CustomAccessDecisionManager();
    }


}